package com.liu.frame.http;

import android.content.Context;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.liu.frame.base.Basebean;
import com.liu.frame.cache.CacheConfig;
import com.liu.frame.config.Api;
import com.liu.frame.utils.GsonUtils;
import com.liu.frame.utils.LoadingUtil;
import com.liu.frame.utils.LogUtils;
import com.liu.frame.utils.NetWorkUtil;
import com.liu.frame.utils.ToastUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.File;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Producer;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by 刘智强 on 2016/10/28.
 * 请求接口和回调的封装
 */
public class WeiLiCaiHttpRequest<T> {
    private OkHttpClient.Builder builder;//OKHTTP的builder对象
    private Retrofit retrofit;//Retrofit对象
    private OkHttpClient okHttpClient;//okhttp对象
    private Context context;//上下文
    private SoftReference<Context> contextSoftReference;
    public IWeiLiCaiHttpService weiLiCaiHttpService;//接口对象
    private CallBack callBack;//回调接口
    private String code;//接口返回的状态码
    private String message;//接口返回的信息
    private String returnInfo;//接口返回的JSON数据
    private File httpCacheDirectory;//缓存文件夹
    private Subscription tmpSubscription;        //取消订阅用的

    public CallBack getCallBack() {
        return callBack;
    }

    public void setCallBack(CallBack callBack) {
        this.callBack = callBack;
    }




    /**
     * 发起请求
     *
     *
     */

    public void postHttpRequest(Observable observable,  final CallBack callBack) {

        /**
         * 没有网络读取缓存
         */
        if (!NetWorkUtil.isNetwork(context)) {
            ToastUtils.myToast(context, "暂无网络");

        } else {
//            IWeiLiCaiHttpService service=retrofit.create(IWeiLiCaiHttpService.class);
//            tmpSubscription=service.login(parametersMap)
//                    .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
//                    .subscribe(new Subscriber<Basebean>() {
//                        @Override
//                        public void onCompleted() {
//                            callBack.completed();
//
//                        }
//
//                        @Override
//                        public void onError(Throwable e) {
//                            callBack.error();
//
//                        }
//
//                        @Override
//                        public void onNext(Basebean basebean) {
//                            callBack.success(basebean);
//
//
//                        }
//                    });

            observable.subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Subscriber<Basebean<T>>() {
                        @Override
                        public void onStart() {
                            super.onStart();
                            Context context = contextSoftReference.get();
                            LoadingUtil.getInstance().showDialog(context, "");
                            Log.e("onStart", "onStart");
                            callBack.start();
                        }

                        @Override
                        public void onCompleted() {
                            LoadingUtil.getInstance().dismissDialog();
                            Log.e("onCompleted", "onCompleted");
                            callBack.completed();
                        }

                        @Override
                        public void onError(Throwable e) {
                            LogUtils.e(e.getMessage());
                            LoadingUtil.getInstance().dismissDialog();
                            callBack.error();
                        }

                        @Override
                        public void onNext(Basebean<T> basebean) {
                            LogUtils.e(basebean.getReturnCode());
                            LogUtils.e(basebean.getReturnMessage());
                            callBack.success(basebean.getReturnCode(),basebean.getReturnMessage(),basebean);


                        }





//                        @Override
//                        public void onNext(Basebean basebean) {
//                            callBack.success(basebean);
//
//                        }

//                        @Override
//                        public void onNext(Basebean<T> response) {
//
////                            returnInfo = GsonUtils.json2String(response, "returnInfo");
////                            code = GsonUtils.json2String(response, "returnCode");
////                            message = GsonUtils.json2String(response, "returnMessage");
//                            LogUtils.e(response.getReturnCode());
//                            LogUtils.e(response.getReturnMessage());
//                            LogUtils.e(response.getT().toString());
////                            Type  jsonType = new TypeToken<T>() {}.getType();
////                            T t=null;
////                            try {
////                                t=  new Gson().fromJson(returnInfo,jsonType);
////
////                            } catch (Exception e) {
////                                e.printStackTrace();
////                            }
////                            Object json=null;
////                            try {
////                                json= new JSONTokener(returnInfo).nextValue();
////                            } catch (JSONException e) {
////                                e.printStackTrace();
////                            }
//
//
//                            switch (code) {
//                                case "00000":
//
////                                    if (json instanceof JSONObject){
////                                        try {
////                                            callBack.success(code, message, GsonUtils.fromJson(returnInfo,));
////                                        } catch (Exception e) {
////                                            LogUtils.e("JSON解析错误!!!");
////                                            e.printStackTrace();
////                                            callBack.fail(code, message, returnInfo);
////                                        }
////                                    }else  if (json instanceof JSONArray){
////                                        try {
////                                            callBack.success(code,message, GsonUtils.fromJsonArray(returnInfo,t.getClass()));
////                                        } catch (Exception e) {
////                                            LogUtils.e("JSON解析错误!!!");
////                                            callBack.fail(code, message, returnInfo);
////                                        }
////                                    }
//
//                                    callBack.success(code, message, );
//                                    break;
//                                case "00001":
//                                    ToastUtils.myToast(context, message);
//                                    CacheConfig.getInstance().cleareCacheByKey(Api.LOGIN);
//
//                                    break;
//
//                                default:
//                                    callBack.fail(code, message, returnInfo);
//                            }
//                        }

                        @Override
                        public void setProducer(Producer p) {
                            super.setProducer(p);
                            Log.e("Producer", "Producer");
                        }
                    });
        }


    }

    public void cancleRequest() {
        if (okHttpClient != null) {
            okHttpClient.dispatcher().cancelAll();
        }
    }

    /**
     * 自定义接口来把数据解析返回到业务层（即调用的地方）
     *
     * @param
     */




    public interface CallBack<T> {
        /**
         * 请求开始
         */
        void start();

        /**
         * 请求完成
         */

        void completed();

        /**
         * 请求出错（主要指网络异常）
         */

        void error();

        /**
         * 请示失败（主要指业务失败 ）
         *
         * @param code
         * @param message
         * @param returnInfo
         */

        void fail(String code, String message, String returnInfo);


        /**
         * 请求成功(主要指业务成功)
         *

         */

        void success(String code, String message, Basebean<T> baseBean) ;


    }

    /**
     * 获取泛型类型
     *
     * @return
     */
    private Class getSuperClass() {
        return getSuperClassGenricType(getClass(), 0);
    }

    /**
     * 通过反射, 获得定义Class时声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
     *
     * @param clazz
     * @param index
     * @return
     */
    private Class<Object> getSuperClassGenricType(final Class clazz, final int index) {

        //返回表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类的 Type。
        Type genType = clazz.getGenericSuperclass();

        if (!(genType instanceof ParameterizedType)) {
            return Object.class;
        }
        //返回表示此类型实际类型参数的 Type 对象的数组。
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

        if (index >= params.length || index < 0) {
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            return Object.class;
        }

        return (Class) params[index];
    }

}
